我们将把细节划分为关于必要条件(正确性)的信息，和对调优有用但对正确性不是必需的信息。\par

第一个正确性类别中，将列举内核正确启动所应满足的条件，不遵守这些设备限制将导致程序失败。图12-7显示了如何获取这些参数中的部分，这些值可以在主机代码和内核代码中使用(通过Lambda捕获)。可以修改代码来利用这些信息，例如：可以调整缓冲区大小或工作组大小。\par

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
提交一个不满足这些条件的内核将生成一个错误。
\end{tcolorbox}

\hspace*{\fill} \par %插入空行
图12-7 获取可用于形成内核的参数
\begin{lstlisting}[caption={}]
std::cout << "We are running on:\n"
		  << dev.get_info<info::device::name>() << "\n";

// Query results like the following can be used to calculate how
// large our kernel invocations should be.
auto maxWG = dev.get_info<info::device::max_work_group_size>();
auto maxGmem = dev.get_info<info::device::global_mem_size>();
auto maxLmem = dev.get_info<info::device::local_mem_size>();

std::cout << "Max WG size is " << maxWG
		  << "\nMax Global memory size is " << maxGmem
		  << "\nMax Local memory size is " << maxLmem << "\n";
\end{lstlisting}

\hspace*{\fill} \par %插入空行
\textbf{查询设备}

\textit{device\_type}: cpu, gpu, accelerator, custom,automatic, host, all。最常使用的是is\_host()， is\_cpu, is\_gpu() (见图12-6):\par

\textit{max\_work\_item\_sizes}: nd\_range的工作组的每个维度中允许的最大工作项数。对于非定制设备，最小值为(1,1,1)。\par

\textit{max\_work\_group\_size}:单个计算单元上执行内核的工作组中允许的最大工作项数。最小值为1。\par

\textit{global\_mem\_size}: 全局内存大小(以字节为单位)。\par

\textit{local\_mem\_size}: 本地内存大小(以字节为单位)。除定制设备外，最小为32K。\par

\textit{extensions}: 特定于设备的信息在SYCL规范中没有特别详细，通常是特定于供应商的，如verycurious 程序所示(图12-6)。\par

\textit{max\_compute\_units}: 说明设备实现定义的可用并行性的数量，请谨慎使用!\par

\textit{sub\_group\_sizes}: 返回设备支持的子工作组大小。\par

\textit{usm\_device\_allocations}: 如果该设备支持显式USM中描述的设备内存，则返回true。\par

\textit{usm\_host\_allocations}: 如果该设备可以访问主机内存，则返回true。\par

\textit{usm\_shared\_allocations}: 如果此设备支持共享内存，则返回true。\par

\textit{usm\_restricted\_shared\_allocations}: 如果该设备支持受设备上“restricted USM”限制所控制的共享内存，则返回true。此属性要求usm\_shared\_allocations对此设备返回true。\par

\textit{usm\_system\_allocator}: 如果系统分配器可能用于此设备上的共享内存，而不是USM分配机制，则返回true.\par

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
我们建议避免在程序逻辑中使用最大计算单元！
\end{tcolorbox}

部分原因是定义不够清晰，在代码调优中没有用处。大多数程序应该表达并行性，并让运行时将其映射为可用的并行性，而不是使用max\_compute\_units。只有在使用特定于实现和设备的信息时，最大计算单元才有意义。专家可能会这样做，但大多数开发人员不这样做，也不需要这样做!在这种情况下，让运行时来完成这项工作!\par

\hspace*{\fill} \par %插入空行
\textbf{查询内核}

第10章“程序对象中的内核”中讨论的机制需要执行这些内核查询:\par

work\_group\_size: 返回可用于在特定设备上执行内核的最大工作组大小\par

compile\_work\_group\_size: 返回由内核指定的工作组大小(如果适用)，否则返回(0,0,0)\par

compile\_sub\_group\_size: 返回由内核指定的子工作组大小(如果适用)，否则返回0\par

compile\_num\_sub\_groups: 返回由内核指定的子工作组的数量(如果适用)，否则返回0\par

max\_sub\_group\_size: 返回以指定工作组大小启动的内核的最大子工作组大小\par

max\_num\_sub\_groups: 返回内核的最大子工作组数\par











